package com.gitee.wsl.compose.mvi

import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.DisposableEffectScope
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import com.gitee.wsl.compose.state.S.state
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow


interface StateView<STATE: UiState<UiEvent>,SCOPE: UiContextScope> {

    val eventFlow: MutableStateFlow<UiEvent>

    var subViewblock:(@Composable SCOPE.(MutableState<STATE>)->Unit)?

    val launched:(CoroutineScope.()->Unit)?

    val dispose:(DisposableEffectScope.()->Unit)?

    val start:(CoroutineScope.()->Unit)?

    val scope:SCOPE

    val stateBuilder:()->STATE

    fun onLaunch(coroutineScope: CoroutineScope){
        launched?.invoke(coroutineScope)
    }
    @Composable
    fun onStart(coroutineScope: CoroutineScope, _state: MutableState<STATE>){
        start?.invoke(coroutineScope)
        subViewblock?.invoke(scope,_state )
    }

    fun onDispose(disposableEffectScope: DisposableEffectScope){
        dispose?.invoke(disposableEffectScope)
    }

    fun onCreateView(block:@Composable SCOPE.( MutableState<STATE>)->Unit){
        subViewblock = block
    }

    /**
     * Entry point for the [MviView] to handle single event.
     */
    fun handleEvent(event: UiEvent) {
        eventFlow.value=event
    }

}

/**
 * object CounterScreen : Screen {
 * data class CounterState(
 *  val count: Int,
 *  val eventSink: (CounterEvent) -> Unit,
 *  ) : CircuitUiState
 *  sealed interface CounterEvent : CircuitUiEvent {
 *    object Increment : CounterEvent
 *    object Decrement : CounterEvent
 *  }
 * }
 *
 * @Composable
 * fun CounterPresenter(): CounterState {
 *  var count by rememberSaveable { mutableStateOf(0) }
 *
 *  return CounterState(count) { event ->
 *      when (event) {
 *      is CounterEvent.Increment -> count++
 *      is CounterEvent.Decrement -> count--
 *     }
 *   }
 * }
 */

interface UiState<EVENT: UiEvent>{
    val eventSink: (EVENT) -> Unit
}

interface UiEvent{
    object NULL: UiEvent
}

interface UiContextScope{
    val modifier: Modifier
}

interface UiGroupContextScope: UiContextScope {}


@Composable
fun <T: UiState<UiEvent>> ViewSetup(stateView: StateView<T, *>) {
    val coroutineScope = rememberCoroutineScope()
    val _state = state(stateView.stateBuilder.invoke())
    DisposableEffect(stateView) {
        stateView.onLaunch(coroutineScope)
        onDispose {
            stateView.onDispose(this)
        }
    }
    stateView.onStart(coroutineScope,_state)
}